import type { AxiosInstance, AxiosResponse } from "axios";
import axios from "axios";
import wxAdapter from "axios-miniprogram-adapter";
import { ungzip } from "pako"
import { TextDecoder } from "text-encoding"
import { useConfigStore } from "@/store";

export interface HttpResponse<T = unknown> extends AxiosResponse {
  code?: number
  message: string
  data: T
  state?: number
}

let instance: AxiosInstance | null = null;

// #ifdef MP-WEIXIN
axios.defaults.adapter = wxAdapter;
// #endif

const baseURL = "https://api.dnftools.com/";

// 解压
function unzip(key: string) {
  // 将二进制字符串转换为字符数组

  const charData = key.split("").map((x) => {
    return x?.charCodeAt(0);
  });

  // 将数字数组转换成字节数组
  const binData = new Uint8Array(charData);

  // 解压
  const data = ungzip(binData);

  const decoder = new TextDecoder();
  const str = decoder.decode(data);

  // unescape(str)  --->解压后解码，防止中午乱码
  return str;
}


function atob(input: string) {
  const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  const str = input.replace(/=+$/, "");
  let output = "";
 
  if (str.length % 4 === 1) {
    throw new Error("InvalidLengthError");
  }
 
  for (let i = 0, len = str.length; i < len; i += 4) {
    const a = chars.indexOf(str.charAt(i));
    const b = chars.indexOf(str.charAt(i + 1));
    const c = chars.indexOf(str.charAt(i + 2));
    const d = chars.indexOf(str.charAt(i + 3));
    const sum = (a << 18) | (b << 12) | (c << 6) | d;
    output += String.fromCodePoint((sum >> 16) & 0xFF, (sum >> 8) & 0xFF, sum & 0xFF);
  }
 
  return output;
}

export function defineRequest<T>(fn: (ax: AxiosInstance) => T) {
  if (!instance) {
    instance = axios.create({
      baseURL
    });

    instance.interceptors.request.use(
      (request) => {
        const configStore = useConfigStore();
        const token = configStore.token;
        request.headers.Client = "mobile"

        if (token) {
          request.headers["Access-Token"] = token;
        }

        return request;
      },
      (error) => {
        // do something
        return Promise.reject(error);
      }
    );

    instance.defaults.headers.post["Content-Type"]
      = "application/json;charset=UTF-8";
    // instance.defaults.headers["Accept-Encoding"] = "gzip"
    // instance.defaults.headers["Content-Encoding"] = "gzip"
    // add response interceptors
    instance.interceptors.response.use(
      async (response: AxiosResponse<HttpResponse>) => {
        if (response.data.code === 500) {
          /* empty */
        }
        // 解密数据
        if (typeof response.data.data == "string") {
          try {
            const data = unzip(atob(response.data.data as string))
            response.data.data = JSON.parse(data)
          } catch (e) {
          }
        }
        return response.data
      },
      async (error: Error) => {
        return Promise.reject(error);
      }
    );
  }

  return fn(Object.create(instance));
}
